#ifndef UIHELPER_H
#define UIHELPER_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "QMouseEvent"
#include "QFileDialog"
#include "QNetworkCookie"
#include "QWebEngineCookieStore"


void MainWindow::StartServer(const QString &name)
{//Запуск сервера
    setWindowTitle("OpenMBFR " + version + " для " + name);

    if(server.listen(name))
    {
        connect(&server, &QLocalServer::newConnection, this, &MainWindow::getNewConnections);//Подключаем обработчик для новых подключений
        getNewConnections();//обрабатываем существующие подключения
    }
}

void MainWindow::getNewConnections()
{//обработка подключений к локальному серверу
    while (server.hasPendingConnections())
    {
        QLocalSocket* socket = server.nextPendingConnection();

        connection_list.push_back(socket);
        connect(socket, &QLocalSocket::readyRead,    this, &MainWindow::readSocket);
        connect(socket, &QLocalSocket::disconnected, this, &MainWindow::disconnectSocket);
    }
}

bool MainWindow::eventFilter(QObject *o, QEvent *event)
{    
    if (event->type() == QEvent::HoverMove && !ControlKeyPressed){
        if(tabs.count() == 0) return QObject::event(event);
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        QWebEngineView *view = getTabById();
        if(mouseEvent->pos().y() >= ui->url_line->height() && mouseEvent->y() <= view->height()){
            QPointF s = view->page()->scrollPosition();

            QPointF p = mouseEvent->localPos();

            //            QString pos = QString::number(mouseEvent->x() - view->pos().x() + rx) + " : " + QString::number(mouseEvent->y() - view->pos().y() );
            QString pos = QString::number(p.x() + s.x()) + " : " + QString::number(p.y() + s.y() - ui->url_line->height());
            ui->cursorPosition->setText(pos);
        }
    }
    else if(event->type() == QEvent::FocusOut || event->type() == QEvent::FocusIn){
        ControlKeyPressed = false;
    }
    return QObject::event(event);
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(Qt::Modifier::CTRL == event->modifiers()){
        ControlKeyPressed = true;
        if(Qt::Key_N == event->key()){
            createTab();
        }
        else if(tabs.count() > 0){
            Tab *tab = getTabById();
            if(Qt::Key_Plus == event->key() || Qt::Key_Equal == event->key()){
                tab->setZoomFactor(tab->zoomFactor() + 0.1);
            }
            else if(Qt::Key_Minus == event->key()){
                tab->setZoomFactor(tab->zoomFactor() - 0.1);
            }
            else if(Qt::Key_0 == event->key()){
                tab->setZoomFactor(1);
            }
            else if(Qt::Key_W == event->key()){
                deleteTab(tab);
            }
        }
    }
}
void MainWindow::keyReleaseEvent(QKeyEvent *event){
    if(Qt::Key_Control == event->key())
        ControlKeyPressed = false;
}

void MainWindow::mousePressEvent(QMouseEvent* event){
#if QT_VERSION_MAJOR == 5
    mouseClick_X = event->x();
    mouseClick_Y = event->y();
#else
    mouseClick_X = event->position().x();
    mouseClick_Y = event->position().y();
#endif
}
void MainWindow::mouseMoveEvent(QMouseEvent* event){
#if QT_VERSION_MAJOR == 5
    move(event->globalX() - mouseClick_X, event->globalY() - mouseClick_Y);
#else
    move(event->globalPosition().x() - mouseClick_X, event->globalPosition().y() - mouseClick_Y);
#endif
}

void MainWindow::SendToServer(QLocalSocket *socket, const QByteArray *str){
    socket->write(*str); socket->waitForBytesWritten();
}

void MainWindow::disconnectSocket()
{//miniPoster отключился
    QLocalSocket * ptrSender = (QLocalSocket*)sender();
    connection_list.removeOne(ptrSender);
    ptrSender->deleteLater();
}

bool MainWindow::isMatchString(QString &string, QStringList strings)
{//проверка совпали ли команды
    return strings.contains(string);
}

void MainWindow::error(Errors err, QLocalSocket *socket){
    SendToServer(socket, getError(err));
}

const QByteArray* MainWindow::getError(Errors err){
    switch (err) {
    case NO_TABS:                    return &NO_TABS_err;
    case BAD_ID:                     return &BAD_ID_err;
    case NO_COMMAND:                 return &NO_COMMAND_err;
    case TAB_NOT_EXISTS:             return &TAB_NOT_EXISTS_err;
    case BAD_CAPTCHA_TYPE:           return &BAD_CAPTCHA_TYPE_err;
    case BAD_COMMAND_NAME:           return &BAD_COMMAND_NAME_err;
    case BAD_PROXY_TYPE_OR_PARAMS:   return &BAD_PROXY_TYPE_OR_PARAMS_err;
    case BAD_COMMAND_PARAM_LIST:     return &BAD_COMMAND_PARAM_LIST_err;
    case BAD_COMMAND_NAME_OR_PARAMS: return &BAD_COMMAND_NAME_OR_PARAMS_err;
    case BAD_MOUSE_EMULATION:        return &BAD_MOUSE_EMULATION_err;
    case TOO_MUCH_PARAMS:            return &TOO_MUCH_PARAMS_err;

    default:                         return &UNDEFINED_ERROR;
    }
}

MainWindow::Commands MainWindow::getCommand(QString *posterCommand){
    if(*posterCommand == "ISLOAD")
        return IS_LOAD;
    if(*posterCommand == "GETURL")
        return GET_URL;
    if(*posterCommand == "OPENURL" ||
            *posterCommand == "OPEN")
        return OPEN_URL;
    if(*posterCommand == "TABFOCUSBYNAME")
        return TAB_FOCUS_BY_NAME;
    if(*posterCommand == "EVALJS")
        return EVAL_JS;
    if(*posterCommand == "SETPROXY")
        return SET_PROXY;
    if(*posterCommand == "SETUSERAGENT")
        return SET_USERAGENT;
    if(*posterCommand == "JSERRORLOGGING")
        return JS_ERROR_LOGGING;
    if(*posterCommand == "JSLOGLEVEL")
        return JS_LOG_LEVEL;
    if(*posterCommand == "JSONERRORALERT")
        return JS_ON_ERROR_ALERT;
    if(*posterCommand == "GETHTML")
        return GET_HTML;
    if(*posterCommand == "SETHTML")
        return SET_HTML;
    if(*posterCommand == "V2")
        return V2;
    if(*posterCommand == "V3")
        return V3;
    if(*posterCommand == "HCAP")
        return HCAP;
    if(*posterCommand == "RR" ||
            *posterCommand == "RECAPTCHARESPONSE")
        return RECAPTCHA_RESPONSE;
    if(*posterCommand == "FORWARD")
        return FORWARD;
    if(*posterCommand == "BACK")
        return BACK;
    if(*posterCommand == "RELOAD")
        return RELOAD;
    if(*posterCommand == "GETIDS")
        return GET_IDS;
    if(*posterCommand == "GETUSERAGENT")
        return GET_USERAGENT;
    if(*posterCommand == "GETTABID")
        return GET_TAB_ID;
    if(*posterCommand == "GETTABCOUNT")
        return GET_TAB_COUNT;
    if(*posterCommand == "CLOSEWINDOW" ||
            *posterCommand == "CLOSE")
        return CLOSE_WINDOW;
    if(*posterCommand == "WINDOWMINIMAZE" ||
            *posterCommand == "MINIMAZE")
        return WINDOW_MINIMAZE;
    if(*posterCommand == "WINDOWRESTORE" ||
            *posterCommand == "RESTORE")
        return WINDOW_RESTORE;
    if(*posterCommand == "ELEMENTSETVALUEBYID")
        return ELEMENT_SET_VALUE_BY_ID;
    if(*posterCommand == "ELEMENTSETVALUEBYCLASS")
        return ELEMENT_SET_VALUE_BY_CLASS;
    if(*posterCommand == "ELEMENTSETINNERHTMLBYID")
        return ELEMENT_SET_INNER_HTML_BY_ID;
    if(*posterCommand == "ELEMENTSETINNERHTMLBYCLASS")
        return ELEMENT_SET_INNER_HTML_BY_CLASS;
    if(*posterCommand == "ELEMENTCLICKBYID")
        return ELEMENT_CLICK_BY_ID;
    if(*posterCommand == "ELEMENTCLICKBYCLASS")
        return ELEMENT_CLICK_BY_CLASS;
    if(*posterCommand == "DELTOR")
        return DEL_TOR;
    if(*posterCommand == "PROXYON" ||
            *posterCommand == "ONPROXY")
        return PROXY_ON;
    if(*posterCommand == "PROXYOFF" ||
            *posterCommand == "OFFPROXY")
        return PROXY_OFF;
    if(*posterCommand == "GETCOOKIES")
        return GET_COOKIES;
    if(*posterCommand == "DELETEALLCOOKIES")
        return DELETE_ALL_COOKIES;
    if(*posterCommand == "JSERROR")
        return JS_ERROR;
    if(*posterCommand == "CLEARJSERRORS" ||
            *posterCommand == "JSCLEARERRORS")
        return CLEAR_JS_ERRORS;
    if(*posterCommand == "ADDTAB")
        return ADD_TAB;
    if(*posterCommand == "ADDTABFOCUS")
        return ADD_TAB_FOCUS;
    if(*posterCommand == "CLOSETAB")
        return CLOSE_TAB;
    if(*posterCommand == "TABFOCUS")
        return TAB_FOCUS;
    if(*posterCommand == "CLOSETABBYNAME")
        return CLOSE_TAB_BY_NAME;
    if(*posterCommand == "ISTABEXISTS")
        return IS_TAB_EXISTS;
    if(*posterCommand == "ISTABNAMEEXISTS")
        return IS_TAB_NAME_EXISTS;
    if(*posterCommand == "SETWINDOWSIZE")
        return SET_WINDOW_SIZE;
    if(*posterCommand == "SETPOSITION")
        return SET_POSITION;
    if(*posterCommand == "TOR")
        return TOR;
    if(*posterCommand == "SETCACHEDIR")
        return SET_CACHE_DIR;
    if(*posterCommand == "SETCOOKIEDIR")
        return SET_COOKIE_DIR;
    if(*posterCommand == "SETOWNCACHEDIR")
        return SET_OWN_CACHE_DIR;
    if(*posterCommand == "SETOWNCOOKIEDIR")
        return SET_OWN_COOKIE_DIR;
    if(*posterCommand == "SETCOOKIES")
        return SET_COOKIES;
    if(*posterCommand == "SETCOOKIESFROMSTRING")
        return SET_COOKIES_FROM_STRING;
    if(*posterCommand == "SAVECOOKIES")
        return SAVE_COOKIES;
    if(*posterCommand == "SAVECOOKIESTOPATH")
        return SAVE_COOKIES_TO_PATH;
    if(*posterCommand == "GETCOOKIEVALUEBYNAME")
        return GET_COOKIE_VALUE_BY_NAME;
    if(*posterCommand == "GETCOOKIEBYDOMAIN")
        return GET_COOKIE_BY_DOMAIN;
    if(*posterCommand == "GETDOMAINCOOKIEVALUEBYNAME" ||
            *posterCommand == "GETDOMAINCOOKIEBYNAME")
        return GET_DOMAIN_COOKIE_VALUE_BY_NAME;
    if(*posterCommand == "MOUSEEMULATION")
        return MOUSE_EMULATION;
    if(*posterCommand == "SCREENSHOT")
        return SCREEN_SHOT;
    if(*posterCommand == "PIXELEXISTS")
        return PIXEL_EXISTS;
    if(*posterCommand == "LBUTTONCLICK" ||
            *posterCommand == "LBC")
        return L_BUTTON_CLICK;
    if(*posterCommand == "RBUTTONCLICK" ||
            *posterCommand == "RBC")
        return R_BUTTON_CLICK;
    if(*posterCommand == "LBUTTONPRESS" ||
            *posterCommand == "LBP")
        return L_BUTTON_PRESS;
    if(*posterCommand == "LBUTTONRELEASE" ||
            *posterCommand == "LBR")
        return L_BUTTON_RELEASE;
    if(*posterCommand == "MOUSEMOVE")
        return MOUSE_MOVE;
    if(*posterCommand == "SETTITLE" ||
            *posterCommand == "SETWINDOWTITLE")
        return SET_WINDOW_TITLE;
    if(*posterCommand == "SETURL")
        return SET_URL;
    if(*posterCommand == "SETACCEPTHEADER")
        return SET_ACCEPT_HEADER;
    if(*posterCommand == "SCROLLY")
        return SCROLL_Y;
    if(*posterCommand == "SCROLLTOY")
        return SCROLL_TO_Y;
    if(*posterCommand == "SCROLLX")
        return SCROLL_X;
    if(*posterCommand == "SCROLLTOX")
        return SCROLL_TO_X;
    if(*posterCommand == "SCROLLYPOSITION")
        return SCROLL_Y_POSITION;
    if(*posterCommand == "SCROLLYMAX")
        return SCROLL_Y_MAX;
    if(*posterCommand == "SCROLLXPOSITION")
        return SCROLL_X_POSITION;
    if(*posterCommand == "SCROLLXMAX")
        return SCROLL_X_MAX;
    if(*posterCommand == "GETPOSITION")
        return GET_POSITION;
    if(*posterCommand == "GETWINDOWSIZE")
        return GET_WINDOW_SIZE;
    if(*posterCommand == "IMAGES")
        return IMAGES;
    if(*posterCommand == "ISJS")
        return IS_JS;
    if(*posterCommand == "ENABLEJS")
        return ENABLE_JS;
    if(*posterCommand == "DISABLEJS")
        return DISABLE_JS;
    if(*posterCommand == "MAXIMIZE" ||
            *posterCommand == "WINDOWMAXIMIZE")
        return WINDOW_MAXIMIZE;
    if(*posterCommand == "ENABLEACCELERATION")
        return ENABLE_ACCELERATION;
    if(*posterCommand == "DISABLEACCELERATION")
        return DISABLE_ACCELERATION;
    if(*posterCommand == "HIDEBAR")
        return HIDE_BAR;
    if(*posterCommand == "SHOWBAR")
        return SHOW_BAR;
    if(*posterCommand == "ISBAR")
        return IS_BAR;

    return undefined;
}

void MainWindow::on_pushButton_clicked(){//Нажата кнопка "Gmail"
    const QString url = "https://mail.google.com/";
    getTabById()->load(QUrl(url));
    ui->url_line->setText(url);
}

void MainWindow::on_pushButton_2_clicked(){//Нажата кнопка "GO!"
    if(tabs.count() == 0) return;

    getTabById()->load(QUrl::fromUserInput(ui->url_line->text()));
}

void MainWindow::on_url_line_returnPressed(){//Нажали Enter в адресной строке
    if(tabs.count() == 0) return;

    getTabById()->load(QUrl::fromUserInput(ui->url_line->text()));
}

void MainWindow::on_btn_saveCookie_clicked(){
    if(tabs.count() == 0) return;

    QString fileName = QFileDialog::getSaveFileName(this,
                                                    "Укажите файл для сохранения кук",
                                                    cookieDir.path());

    if(fileName.length() == 0) return;
    Tab *tab = getTabById();
    if(tab == nullptr) return;
    tab->saveCookies("", fileName, false, false);
}

void MainWindow::on_btn_removeCookie_clicked(){
    if(tabs.count() == 0) return;

    getTabById()->deleteCookies();
}

int MainWindow::createTab(QString name){//создать новую вкладку
    mutex.lock();
    Tab *tab = new Tab;
    tabs.append(tab);

    ui->tabWidget->addTab(tab, name.length() > 0
                          ? name :
                            "Tab_" + QString::number(tab->id));

    mutex.unlock();

    connect(tab, &QWebEngineView::loadProgress, ui->progressBar, &QProgressBar::setValue);

    return tab->id;
}

bool MainWindow::deleteTab(Tab* tab){//закрыть вкладку и почистить за собой
    if(tabs.count() == 0) return false;
    mutex.lock();

    if(tab == nullptr) return false;

    int index = ui->tabWidget->indexOf(tab);
    ui->tabWidget->removeTab(index);

    tabs.removeOne(tab);
    delete tab;
    mutex.unlock();
    return true;
}

Tab* MainWindow::getTabById(int tabId){
    if(tabId == -1)
        return getTabByWidget(ui->tabWidget->currentWidget());

    for(auto tab : tabs)
        if(tab->id == tabId)
            return tab;
    return nullptr;
}

Tab* MainWindow::getTabByWidget(QWidget *w){
    for(auto tab : tabs)
        if(tab == w)
            return tab;
    return nullptr;
}

void MainWindow::tabChanged(int index){//выбрана другая вкладка -> меняем url
    if(index == -1) { ui->url_line->setText(""); return; }

    Tab *tab = getTabById();
    ui->url_line->setText(tab->page()->url().toString());
}

void MainWindow::on_tabWidget_tabCloseRequested(int index){
    deleteTab(getTabByWidget(ui->tabWidget->widget(index)));
}

int MainWindow::tabFocus(int tabId){//сделать вкладку активной по её id
    if(tabs.count() == 0) return 0;
    Tab *tab = getTabById(tabId);

    int index = ui->tabWidget->indexOf(tab);
    ui->tabWidget->setCurrentIndex(index);
    return 1;
}

bool MainWindow::isTabExist(int tabId){
    return getTabById(tabId) != nullptr;
}

bool MainWindow::isTabNameExist(QString tabName){
    for(int i = 0; i < ui->tabWidget->count(); ++i)
        if(ui->tabWidget->tabText(i) == tabName)
            return true;

    return false;//не существует
}

void MainWindow::save_position_and_pseudo_minimaze(){
    if(!isMinimized){
        normal_pos = pos();

        QSize s = size();
        move(-s.width(), -s.height());

        isMinimized = true;
    }
}

void MainWindow::restore_position_and_show_normal(){
    if(isMinimized){
        move(normal_pos);

        isMinimized = false;
    }
    else showNormal();
}

void MainWindow::setCachePath(Tab *tab, QString path){
    tab->page()->profile()->setCachePath("../save/cacheChrom/" + path);
}
void MainWindow::setCookiePath(Tab *tab, QString path){
    tab->page()->profile()->setPersistentStoragePath("../save/coockieChrom/" + path);
}

#endif // UIHELPER_H
